package com.matrix.order.infrastructure.gateway.acl;

import com.matrix.api.marketing.MarketingApi;
import com.matrix.api.marketing.dto.RefundCalculationRequestDTO;
import com.matrix.api.marketing.vo.RefundCalculationResultVO;
import com.matrix.common.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.RpcException;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * @author 有点甜
 * @since 2025/8/2
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class MarketingAcl {

    @DubboReference(check = false, timeout = 3000)
    private MarketingApi marketingApi;

    public void addPointsForOrder(Long userId, BigDecimal orderAmount, String orderId) {
        if (orderAmount == null || orderAmount.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        try {
            marketingApi.addPointsForOrder(userId, orderAmount, orderId);
            log.info("已为完成的订单 {} 发起增加积分请求。", orderId);
        } catch (RpcException e) {
            log.error("为订单 {} 增加积分失败, RPC调用异常: {}", orderId, e.getMessage());
        }
    }

    @Retryable(
            retryFor  = { RpcException.class },
            backoff = @Backoff(delay = 500, multiplier = 2)
    )
    public BigDecimal useCoupon(Long userId, Long couponId, Long orderId) {
        if (couponId == null || couponId <= 0) {
            return BigDecimal.ZERO;
        }
        try {
            return marketingApi.useCoupon(userId, couponId, orderId);
        } catch (RpcException e) {
            log.error("调用营销服务使用优惠券异常, couponId: {}, RPC异常: {}", couponId, e.getMessage());
            if (e.getCause() instanceof BusinessException) {
                throw (BusinessException) e.getCause();
            }
            throw new BusinessException("优惠券服务暂不可用,请稍后重试");
        }
    }

    public void releaseCoupon(Long couponId) {
        if (couponId == null || couponId <= 0) {
            return;
        }
        try {
            marketingApi.releaseCoupon(couponId);
            log.info("已请求释放优惠券, couponId: {}", couponId);
        } catch (RpcException e) {
            log.error("调用营销服务释放优惠券异常, couponId: {}, RPC异常: {}", couponId, e.getMessage());
        }
    }

    public BigDecimal getCouponDiscount(Long userCouponId) {
        if (userCouponId == null || userCouponId <= 0) {
            return BigDecimal.ZERO;
        }
        try {
            return marketingApi.getCouponDiscount(userCouponId);
        } catch (RpcException e) {
            log.error("Failed to get coupon discount for userCouponId: {}, RPC Exception: {}", userCouponId, e.getMessage());
            return BigDecimal.ZERO;
        }
    }

    public RefundCalculationResultVO processCouponRefund(RefundCalculationRequestDTO request) {
        try {
            return marketingApi.processCouponForRefund(request);
        } catch (RpcException e) {
            log.error("RPC call to processCouponForRefund failed for orderId: {}. Returning default no-refund result.", request.getOrderId(), e);
            return RefundCalculationResultVO.builder()
                    .cashRefundAmount(BigDecimal.ZERO)
                    .pointsAwarded(0)
                    .processingLog("调用营销服务计算退款失败,已阻止退款。")
                    .build();
        }
    }

    public void updateCouponOrderId(Long userCouponId, Long orderId) {
        if (userCouponId == null || userCouponId <= 0) {
            return;
        }
        try {
            marketingApi.updateCouponOrderId(userCouponId, orderId);
        } catch (RpcException e) {
            log.error("CRITICAL: 更新优惠券 {} 的订单ID为 {} 失败. 需要手动核对数据! Error: {}", userCouponId, orderId, e.getMessage());
            throw new BusinessException("关联优惠券与订单失败,请稍后重试");
        }
    }
}